/**
 * Copyright (c) 2006-2015, JGraph Ltd
 * Copyright (c) 2006-2015, Gaudenz Alder
 */
var mxClipboard = {
  /**
   * Class: mxClipboard
   *
   * Singleton that implements a clipboard for graph cells.
   *
   * Example:
   *
   * (code)
   * mxClipboard.copy(graph);
   * mxClipboard.paste(graph2);
   * (end)
   *
   * This copies the selection cells from the graph to the clipboard and
   * pastes them into graph2.
   *
   * For fine-grained control of the clipboard data the <mxGraph.canExportCell>
   * and <mxGraph.canImportCell> functions can be overridden.
   *
   * To restore previous parents for pasted cells, the implementation for
   * <copy> and <paste> can be changed as follows.
   *
   * (code)
   * mxClipboard.copy = function(graph, cells)
   * {
   *   cells = cells || graph.getSelectionCells();
   *   var result = graph.getExportableCells(cells);
   *
   *   mxClipboard.parents = new Object();
   *
   *   for (var i = 0; i < result.length; i++)
   *   {
   *     mxClipboard.parents[i] = graph.model.getParent(cells[i]);
   *   }
   *
   *   mxClipboard.insertCount = 1;
   *   mxClipboard.setCells(graph.cloneCells(result));
   *
   *   return result;
   * };
   *
   * mxClipboard.paste = function(graph)
   * {
   *   if (!mxClipboard.isEmpty())
   *   {
   *     var cells = graph.getImportableCells(mxClipboard.getCells());
   *     var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
   *     var parent = graph.getDefaultParent();
   *
   *     graph.model.beginUpdate();
   *     try
   *     {
   *       for (var i = 0; i < cells.length; i++)
   *       {
   *         var tmp = (mxClipboard.parents != null && graph.model.contains(mxClipboard.parents[i])) ?
   *              mxClipboard.parents[i] : parent;
   *         cells[i] = graph.importCells([cells[i]], delta, delta, tmp)[0];
   *       }
   *     }
   *     finally
   *     {
   *       graph.model.endUpdate();
   *     }
   *
   *     // Increments the counter and selects the inserted cells
   *     mxClipboard.insertCount++;
   *     graph.setSelectionCells(cells);
   *   }
   * };
   * (end)
   *
   * Variable: STEPSIZE
   *
   * Defines the step size to offset the cells after each paste operation.
   * Default is 10.
   */
  STEPSIZE: 10,

  /**
   * Variable: insertCount
   *
   * Counts the number of times the clipboard data has been inserted.
   */
  insertCount: 1,

  /**
   * Variable: cells
   *
   * Holds the array of <mxCells> currently in the clipboard.
   */
  cells: null,

  /**
   * Function: setCells
   *
   * Sets the cells in the clipboard. Fires a <mxEvent.CHANGE> event.
   */
  setCells: function (cells) {
    mxClipboard.cells = cells;
  },

  /**
   * Function: getCells
   *
   * Returns  the cells in the clipboard.
   */
  getCells: function () {
    return mxClipboard.cells;
  },

  /**
   * Function: isEmpty
   *
   * Returns true if the clipboard currently has not data stored.
   */
  isEmpty: function () {
    return mxClipboard.getCells() == null;
  },

  /**
   * Function: cut
   *
   * Cuts the given array of <mxCells> from the specified graph.
   * If cells is null then the selection cells of the graph will
   * be used. Returns the cells that have been cut from the graph.
   *
   * Parameters:
   *
   * graph - <mxGraph> that contains the cells to be cut.
   * cells - Optional array of <mxCells> to be cut.
   */
  cut: function (graph, cells) {
    cells = mxClipboard.copy(graph, cells);
    mxClipboard.insertCount = 0;
    mxClipboard.removeCells(graph, cells);

    return cells;
  },

  /**
   * Function: removeCells
   *
   * Hook to remove the given cells from the given graph after
   * a cut operation.
   *
   * Parameters:
   *
   * graph - <mxGraph> that contains the cells to be cut.
   * cells - Array of <mxCells> to be cut.
   */
  removeCells: function (graph, cells) {
    graph.removeCells(cells);
  },

  /**
   * Function: copy
   *
   * Copies the given array of <mxCells> from the specified
   * graph to <cells>. Returns the original array of cells that has
   * been cloned. Descendants of cells in the array are ignored.
   *
   * Parameters:
   *
   * graph - <mxGraph> that contains the cells to be copied.
   * cells - Optional array of <mxCells> to be copied.
   */
  copy: function (graph, cells) {
    cells = cells || graph.getSelectionCells();
    var result = graph.getExportableCells(graph.model.getTopmostCells(cells));
    mxClipboard.insertCount = 1;
    mxClipboard.setCells(graph.cloneCells(result));

    return result;
  },

  /**
   * Function: paste
   *
   * Pastes the <cells> into the specified graph restoring
   * the relation to <parents>, if possible. If the parents
   * are no longer in the graph or invisible then the
   * cells are added to the graph's default or into the
   * swimlane under the cell's new location if one exists.
   * The cells are added to the graph using <mxGraph.importCells>
   * and returned.
   *
   * Parameters:
   *
   * graph - <mxGraph> to paste the <cells> into.
   */
  paste: function (graph) {
    var cells = null;

    if (!mxClipboard.isEmpty()) {
      cells = graph.getImportableCells(mxClipboard.getCells());
      var delta = mxClipboard.insertCount * mxClipboard.STEPSIZE;
      var parent = graph.getDefaultParent();
      cells = graph.importCells(cells, delta, delta, parent);

      // Increments the counter and selects the inserted cells
      mxClipboard.insertCount++;
      graph.setSelectionCells(cells);
    }

    return cells;
  },
};
